﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.Reflection;
using System.IO;
using System.Diagnostics;

namespace template_dll
{
    public partial class ChildForm : Form
    {
        public ChildForm()
        {
            InitializeComponent();
        }

        private const string namechcol = "Флаг";
        private SqlConnection conn;
        private DataTable dt_rep;
        private delegate void Deleg();
        private Deleg del;
        private Guid guid;
        private DataTable dt_tree;
        private DataTable pharm;
        private DataTable suppl;
        private struct Dict { public int id; public string text; }
        private Dict[] doctype;
        private int[] tr;
        private string connstr;

        public static bool DisplayForm(System.Windows.Forms.Form theMDIParent)
        {
            ChildForm f = new ChildForm();
            f.MdiParent = theMDIParent;
            f.WindowState = FormWindowState.Maximized;
            f.Show();
            return true;
        }

        private string GetServ(string filename)
        {
            string str = "";
            using (StreamReader streamReader = new StreamReader(filename))
            {
                while (!streamReader.EndOfStream)
                {
                    str += streamReader.ReadLine();
                }
            }
            return str;
        }

        private void ChildForm_Load(object sender, EventArgs e)
        {
            connstr = @"Server=" + GetServ("serv.txt") + ";Database=PharmOLAPDW;Integrated Security=True";
            conn = new SqlConnection(connstr);
            dt_rep = new DataTable();
            guid = Guid.NewGuid();
            TrViewLoad();
            dateTimePicker1.Value = DateTime.Now.Date.AddDays(-1);
            dateTimePicker2.Value = DateTime.Now.Date.AddDays(-1);
            listBox1.Items.Add("(Все)");
            listBox2.Items.Add("(Все)");
            toolStripStatusLabel1.Text = "";
            pharm = new DataTable();
            suppl = new DataTable();
            pharm.Load(ProcSel(conn, @"pas_PharmSel"));
            foreach (DataColumn dc in pharm.Columns)
            {
                if (dc.ColumnName != "Флаг") dc.ReadOnly = true;
                else dc.ReadOnly = false;
            }
            suppl.Load(ProcSel(conn, @"pas_SupplSel"));
            foreach (DataColumn dc in suppl.Columns)
            {
                if (dc.ColumnName != "Флаг") dc.ReadOnly = true;
                else dc.ReadOnly = false;
            }
            DataTable dt_d = new DataTable();
            dt_d.Load(ProcSel(conn, @"pas_DocTypeSel"));
            doctype = new Dict[dt_d.Rows.Count];

            for (int i = 0; i < dt_d.Rows.Count; i++)
            {
                object[] ob = dt_d.Rows[i].ItemArray;
                doctype[i].id = (int)ob[0];
                doctype[i].text = ob[1].ToString();
                checkedListBox1.Items.Add(doctype[i].text);
            }
        }

        private SqlDataReader ProcSel(SqlConnection con, string procname)
        {
            SqlCommand com = con.CreateCommand();
            com.CommandType = CommandType.StoredProcedure;
            com.CommandText = procname;
            if (con.State == ConnectionState.Closed) con.Open();
            return com.ExecuteReader();
        }

        private void StartCreateRep(object sender, EventArgs e)
        {
            if (CheckTree(treeView1))
            {
                if (CheckListBox(checkedListBox1) || checkBox_bal.Checked)
                {
                    dataGridView1.DataSource = null;
                    dt_rep = null;
                    dt_rep = new DataTable();
                    del = new Deleg(CreateRep);
                    this.Text += " Формируется";
                    IAsyncResult asyncRes = del.BeginInvoke(new AsyncCallback(CallBackFunc), null); //
                    panel1.Enabled = false;
                    dataGridView1.Enabled = false;
                }
                else MessageBox.Show("Необходимо выбрать тип документов или остаток");
            }
            else MessageBox.Show("Необходимо выбрать каталог");
        }

        private void CallBackFunc(IAsyncResult aRes)
        {
            del.EndInvoke(aRes);
            panel1.Invoke((Func<bool>)(() => panel1.Enabled = true));
            dataGridView1.Invoke((Func<bool>)(() => dataGridView1.Enabled = true));
            this.Invoke((Func<string>)(() => this.Text = this.Text.Replace(" Формируется", "")));
            dataGridView1.Invoke((Func<object>)(() => dataGridView1.DataSource = dt_rep.DefaultView));
            statusStrip1.Invoke((Func<string>)(() => toolStripStatusLabel1.Text = "Всего строк: " + dataGridView1.RowCount.ToString()));
        }

        private void CreateRep()
        {
            if (conn.State == ConnectionState.Closed) conn.Open();
            try
            {
                SqlCommand myCommand = conn.CreateCommand();
                myCommand.CommandType = CommandType.StoredProcedure;
                myCommand.CommandText = @"pas_GuidNatureCodeINS";
                myCommand.Parameters.Add("@guid", SqlDbType.UniqueIdentifier);
                myCommand.Parameters.Add("@code", SqlDbType.Int);
                myCommand.Parameters.Add("@del", SqlDbType.Bit);
                myCommand.Parameters.Add("@nature", SqlDbType.VarChar, 5);

                if (conn.State == ConnectionState.Closed) conn.Open();

                myCommand.Parameters["@guid"].Value = guid;
                myCommand.Parameters["@code"].Value = null;
                myCommand.Parameters["@del"].Value = true;
                myCommand.Parameters["@nature"].Value = null;
                myCommand.ExecuteNonQuery();

                guid = Guid.NewGuid();

                for (int i = 0; i < checkedListBox1.Items.Count; i++)
                {
                    if (checkedListBox1.GetItemChecked(i))
                    {
                        myCommand.Parameters["@guid"].Value = guid;
                        myCommand.Parameters["@code"].Value = doctype[i].id;
                        myCommand.Parameters["@del"].Value = false;
                        myCommand.Parameters["@nature"].Value = "docs";
                        myCommand.ExecuteNonQuery();
                    }
                }
                tr = null;
                tr = new int[] { };
                CheckTreeID(this.treeView1);
                foreach (int i in tr)
                {
                    myCommand.Parameters["@guid"].Value = guid;
                    myCommand.Parameters["@code"].Value = i;
                    myCommand.Parameters["@del"].Value = false;
                    myCommand.Parameters["@nature"].Value = "cat";
                    myCommand.ExecuteNonQuery();
                }
                if (pharm != null)
                    foreach (DataRow dr in pharm.Rows)
                        if (Convert.ToBoolean(dr[namechcol]) == true)
                        {
                            myCommand.Parameters["@guid"].Value = guid;
                            myCommand.Parameters["@code"].Value = Convert.ToInt32(dr["Код"]); ;
                            myCommand.Parameters["@del"].Value = false;
                            myCommand.Parameters["@nature"].Value = "pharm";
                            myCommand.ExecuteNonQuery();
                        }
                if (suppl != null)
                    foreach (DataRow dr in suppl.Rows)
                        if (Convert.ToBoolean(dr[namechcol]) == true)
                        {
                            myCommand.Parameters["@guid"].Value = guid;
                            myCommand.Parameters["@code"].Value = Convert.ToInt32(dr["Код"]); ;
                            myCommand.Parameters["@del"].Value = false;
                            myCommand.Parameters["@nature"].Value = "suppl";
                            myCommand.ExecuteNonQuery();
                        }

                
                dt_rep.Load(RepProc(guid, conn));

                myCommand.Parameters["@guid"].Value = guid;
                myCommand.Parameters["@code"].Value = null;
                myCommand.Parameters["@del"].Value = true;
                myCommand.Parameters["@nature"].Value = null;
                myCommand.ExecuteNonQuery();

                conn.Close();
            }
            catch (Exception ex)
            {
                conn.Close();
                conn = null;
                conn = new SqlConnection(connstr);
                MessageBox.Show(ex.ToString());
            }

        }

        private SqlDataReader RepProc(Guid id, SqlConnection sqlcon)
        {
            SqlCommand sqlcom = sqlcon.CreateCommand();
            sqlcom.CommandType = CommandType.StoredProcedure;
            sqlcom.CommandText = @"pas_CatalogsReport";
            sqlcom.CommandTimeout = 600;

            //sqlcom.Parameters.Add("@guid", SqlDbType.UniqueIdentifier);
            //sqlcom.Parameters["@guid"].Value = id;

            sqlcom.Parameters.AddWithValue("@guid",id);
            sqlcom.Parameters.AddWithValue("@docs",checkBox_docs.Checked);
            sqlcom.Parameters.AddWithValue("@day", radioButton1.Checked);
            sqlcom.Parameters.AddWithValue("@month", radioButton2.Checked);
            sqlcom.Parameters.AddWithValue("@quarter", radioButton3.Checked);
            sqlcom.Parameters.AddWithValue("@year", radioButton4.Checked);
            sqlcom.Parameters.AddWithValue("@pharm",checkBox_pharm.Checked);
            sqlcom.Parameters.AddWithValue("@catal",true);
            sqlcom.Parameters.AddWithValue("@drug",checkBox_drug.Checked);
            sqlcom.Parameters.AddWithValue("@arch", checkBox_arch.Checked);
            sqlcom.Parameters.AddWithValue("@datebeg",dateTimePicker1.Value.Date);
            sqlcom.Parameters.AddWithValue("@dateend",dateTimePicker2.Value.Date);
            sqlcom.Parameters.AddWithValue("@balance", checkBox_bal.Checked);
            sqlcom.Parameters.AddWithValue("@sup", checkBox_sup.Checked);

            return sqlcom.ExecuteReader();
        }

        private void ExpToExcel(object sender, EventArgs e)
        {
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.FileName = "Каталоги списков";
            sfd.Filter = "Файл CSV | *.csv";
            if (sfd.ShowDialog() == DialogResult.OK)
            {   
                SaveDGVToCSVfile(sfd.FileName.ToString(), dataGridView1, true);
            }
        }

        public static bool SaveDGVToCSVfile(string filename, DataGridView table, bool openInExcel)
        {
            try
            {
                StreamWriter sw = new StreamWriter(filename, false, Encoding.Unicode);

                List<int> col_n = new List<int>();
                foreach (DataGridViewColumn col in table.Columns)
                    if (col.Visible)
                    {
                        sw.Write(col.HeaderText + "\t");
                        col_n.Add(col.Index);
                    }
                sw.WriteLine();
                int x = table.RowCount;
                if (table.AllowUserToAddRows) x--;

                for (int i = 0; i < x; i++)
                {
                    for (int y = 0; y < col_n.Count; y++)
                        sw.Write(table[col_n[y], i].Value + "\t");
                    sw.Write(" \r\n");
                }
                sw.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Ошибка!", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                return false;
            }

            if (openInExcel)
            {
                try
                {
                    Process newProc = Process.Start("excel.exe", "\"" + filename + "\"");
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "Ошибка!", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                }
            }
            return true;
        }


        private void TrViewLoad()
        {
            dt_tree = null;
            dt_tree = new DataTable();
            string sp_name = @"pas_BrandTreeSel";
            SqlCommand comm = new SqlCommand();
            comm.CommandType = CommandType.StoredProcedure;
            comm.Connection = conn;
            comm.CommandText = sp_name;
            comm.Parameters.AddWithValue("@drugs", 0);

            if (conn.State == ConnectionState.Closed) conn.Open();
            dt_tree.Load(comm.ExecuteReader());

            TreeNode tn = new TreeNode();
            DataView dv = new DataView(dt_tree);
            DataTable dt_dis = dv.ToTable(true, "BrandName1");
            foreach (DataRow dr in dt_dis.Rows)
            {
                TreeNode tn1 = new TreeNode();
                tn1.Text = dr[0].ToString();
                treeView1.Nodes.Add(tn1);
            }
            foreach (TreeNode treenode in treeView1.Nodes)
            {
                string[] selparamval = new string[1];
                selparamval[0] = treenode.Text;
                TreeNodeLoad(2, selparamval, treenode, dt_tree);
            }
        }

        private TreeNode TreeNodeLoad(int col, string[] selparamval, TreeNode node, DataTable table)
        {
            if (col <= 6)
            {
                string[] param = new string[] { };
                string selparam = "";
                for (int i = 0; i < col; i++)
                {
                    if (i < 5)
                    {
                        Array.Resize(ref param, param.Length + 1);
                        param[param.Length - 1] = "BrandName" + (i + 1).ToString();
                        if (i < col - 1)
                        {
                            if (selparam != "") selparam += " and ";
                            selparam += param[i] + " = '" + selparamval[i] + "'";
                        }
                    }

                }
                string[] newselparam = selparamval;
                Array.Resize(ref newselparam, newselparam.Length + 1);
                foreach (DataRow dr in (new DataView(table)).ToTable(true, param).Select(selparam))
                {
                    if (col < 6)
                    {
                        if (dr[param[col - 1]].ToString() != "")
                        {
                            int ind = node.Nodes.Add(dr[param[col - 1]].ToString()).Index;
                            newselparam[newselparam.Length - 1] = node.Nodes[ind].Text;
                            TreeNodeLoad(col + 1, newselparam, node.Nodes[ind], table);
                        }
                        if (dr[param[col - 1]].ToString() == "")
                        {
                            string s = dt_tree.Select(selparam)[0]["BrandID"].ToString();
                            node.ToolTipText = dt_tree.Select(selparam)[0]["BrandID"].ToString();
                        }
                    }
                    else
                    {
                        node.ToolTipText = dt_tree.Select(selparam)[0]["BrandID"].ToString();
                    }
                }
            }
            return node;
        }

        private void treeView1_AfterCheck(object sender, TreeViewEventArgs e)
        {
           // The code only executes if the user caused the checked state to change.
           if(e.Action != TreeViewAction.Unknown)
           {
              if(e.Node.Nodes.Count > 0)
              {
                 /* Calls the CheckAllChildNodes method, passing in the current 
                 Checked value of the TreeNode whose checked state changed. */
                 this.CheckAllChildNodes(e.Node, e.Node.Checked);
              }
           }
        }
       
        private void CheckAllChildNodes(TreeNode treeNode, bool nodeChecked)
        {
           foreach(TreeNode node in treeNode.Nodes)
           {
              node.Checked = nodeChecked;
              if(node.Nodes.Count > 0)
              {
                 this.CheckAllChildNodes(node, nodeChecked);
              }
           }
        }

        private void checkBox_docsall_CheckedChanged(object sender, EventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {
            int fl = 0;
            listBox1.Items.Clear();
            pharm = FiltFormShow("Аптеки", namechcol, "Аптека", pharm);
            fl = 0;
            foreach (DataRow dr in pharm.Rows)
            {
                if (Convert.ToBoolean(dr["Флаг"]))
                {
                    fl++;
                    listBox1.Items.Add(dr["Аптека"].ToString());
                }
            }
            if (fl == 0) listBox1.Items.Add("(Все)");
        }

        public DataTable FiltFormShow(string formname, string flname, string sort, DataTable dt)
        {
            PharmFilter.PharmFilter f = new PharmFilter.PharmFilter();
            f.Name = formname;
            f.dataGridView1.DataSource = dt.DefaultView;
            f.namechcol = flname;
            f.sortcoumn = sort;
            f.ShowDialog();
            f.Close();
            f = null;
            return dt;
        }

        private bool CheckNodes(TreeNode treeNode)
        {
            int fl = 0;
            foreach (TreeNode node in treeNode.Nodes)
            {
                if (node.Checked) fl++;
                else
                {
                    if (node.Nodes.Count > 0) 
                        if(CheckNodes(node)) fl++;
                }
            }
            if (fl > 0) return true;
            else return false;
        }

        private bool CheckTree(TreeView tree)
        {
            foreach (TreeNode node in tree.Nodes)
            {
                if (CheckNodes(node)) return true;
            }
            return false;
        }

        private bool CheckListBox(CheckedListBox clb)
        {
            for (int i = 0; i < clb.Items.Count; i++)
            {
                if (clb.GetItemChecked(i)) return true;
            }
            return false;
        }

        private void CheckTreeID(TreeView tree)
        {
            foreach (TreeNode node in tree.Nodes)
            {
                this.CheckNodesID(node);
            }
        }

        private void CheckNodesID(TreeNode treeNode)
        {
            foreach (TreeNode node in treeNode.Nodes)
            {
                if (node.Checked)
                {
                    if (node.ToolTipText != "")
                    {
                        Array.Resize(ref tr, tr.Length + 1);
                        tr[tr.Length - 1] = Convert.ToInt32(node.ToolTipText);
                    }
                }
                if (node.Nodes.Count > 0)
                {
                    this.CheckNodesID(node);
                }
            }
        }

        private void treeView1_DoubleClick(object sender, EventArgs e)
        {
            MessageBox.Show(treeView1.SelectedNode.ToolTipText);
        }

        private void dateTimePicker1_ValueChanged(object sender, EventArgs e)
        {

        }

        private void dateTimePicker2_ValueChanged(object sender, EventArgs e)
        {

        }

        private void button4_Click(object sender, EventArgs e)
        {
            int fl = 0;
            listBox2.Items.Clear();
            pharm = FiltFormShow("Поставщики", namechcol, "Поставщик", suppl);
            fl = 0;
            foreach (DataRow dr in suppl.Rows)
            {
                if (Convert.ToBoolean(dr["Флаг"]))
                {
                    fl++;
                    listBox2.Items.Add(dr["Поставщик"].ToString());
                }
            }
            if (fl == 0) listBox2.Items.Add("(Все)");

        }

    }
}
